package com.alstudio.utils.android.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Set;

import android.text.TextUtils;

import com.alstudio.utils.log.ALLog;

public class AndroidNetUtils {

	public static void downloadFromUrl(String inputUrl, OutputStream os)
			throws IOException {
		URL url = new URL(inputUrl);

		long startTime = System.currentTimeMillis();
		ALLog.d("download begining");
		ALLog.d("download url:" + url);
		URLConnection connection = url.openConnection();
		connection.setConnectTimeout(5000);
		long downloaded = 0;
		byte buffer[];
		InputStream stream = connection.getInputStream();
		long size = (long) connection.getContentLength();
		while (true) {
			buffer = (size - downloaded) > 1024 ? new byte[1024]
					: new byte[(int) (size - downloaded)];
			int read = stream.read(buffer);
			if (read == -1) {
				break;
			}
			os.write(buffer, 0, read);
			downloaded += read;
		}
		stream.close();
		os.close();
		ALLog.d("download finished in "
				+ ((System.currentTimeMillis() - startTime) / 1000)
				+ " sec.file size " + downloaded);
	}

	public static HttpURLConnection buildHttpUrlConnectionUsingGetMethod(
			String urlString, HashMap<String, String> headers)
			throws IOException {
		ALLog.d("正在创建HTTP连接: " + urlString);

		disableConnectionReuseIfNecessary();

		HttpURLConnection conn = buildHttpUrlConnection(urlString);

		if (headers != null && headers.size() > 0) {

			Set<String> keySet = headers.keySet();

			for (String s : keySet) {
				conn.setRequestProperty(s, headers.get(s));
			}
		}
		ALLog.d("http 连接已创建！开始连接");
		return conn;
	}

	/**
	 * Returns an {@link InputStream} using {@link HttpURLConnection} to connect
	 * to the given URL.
	 */
	public static InputStream downloadUrl(String urlString) throws IOException {
		HttpURLConnection conn = buildHttpUrlConnection(urlString);
		conn.connect();

		InputStream stream = conn.getInputStream();
		return stream;
	}

	/**
	 * Returns an {@link HttpURLConnection} using sensible default settings for
	 * mobile and taking care of buggy behavior prior to Froyo.
	 */
	public static HttpURLConnection buildHttpUrlConnection(String urlString)
			throws MalformedURLException, IOException {
		disableConnectionReuseIfNecessary();
		ALLog.d("正在创建HTTP连接对象: " + urlString);
		URL url = new URL(urlString);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setReadTimeout(30000 /* milliseconds */);
		conn.setConnectTimeout(30000 /* milliseconds */);
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setRequestMethod("GET");

		conn.setRequestProperty("keepAlive", "false");
		conn.setRequestProperty("Connection", "close");
		ALLog.d("HTTP已创建!开始连接...");
		return conn;
	}

	/**
	 * Prior to Android 2.2 (Froyo), {@link HttpURLConnection} had some
	 * frustrating bugs. In particular, calling close() on a readable
	 * InputStream could poison the connection pool. Work around this by
	 * disabling connection pooling.
	 */
	public static void disableConnectionReuseIfNecessary() {
		// HTTP connection reuse which was buggy pre-froyo
		System.setProperty("http.keepAlive", "false");
	}

	public static Socket buildSocketConnection(String ip, String port)
			throws IOException {

		if (TextUtils.isEmpty(ip)) {
			throw new IllegalArgumentException("ip address should not null");
		}

		if (TextUtils.isEmpty(port)) {
			throw new IllegalArgumentException("port address should not null");
		}

		if (!TextUtils.isDigitsOnly(port)) {
			throw new IllegalArgumentException(
					"port should just need digits only");
		}

		InetSocketAddress sa = new InetSocketAddress(ip, Integer.parseInt(port));

		Socket socket = new Socket();

		/* 设定超时时间为10S */
		socket.connect(sa, 10000);
		return socket;
	}

	public static Socket buildSocketConnection(String ip, String port,
			String timeout) throws NumberFormatException, IOException {

		if (TextUtils.isEmpty(ip)) {
			throw new IllegalArgumentException("ip address should not null");
		}

		if (TextUtils.isEmpty(port)) {
			throw new IllegalArgumentException("ip address should not null");
		}

		if (TextUtils.isEmpty(timeout)) {
			throw new IllegalArgumentException("ip address should not null");
		}

		if (!TextUtils.isDigitsOnly(port)) {
			throw new IllegalArgumentException(
					"port should just need digits only");
		}

		if (!TextUtils.isDigitsOnly(timeout)) {
			throw new IllegalArgumentException(
					"timeout should just need digits only");
		}

		InetSocketAddress sa = new InetSocketAddress(ip, Integer.parseInt(port));

		Socket socket = new Socket();

		socket.connect(sa, Integer.parseInt(timeout));
		return socket;
	}

	public static void closeSocket(Socket s) {

		if (s != null) {
			try {
				s.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	public interface HttpDownloadCallback {

		public void onDownloadFinished(boolean result);

	}

}
